/*
 * CacheServer.h
 *
 *  Created on: 2013. 8. 5.
 *      Author: jjaehuny
 */

#ifndef PROJECTZ_NPROXY_CACHESERVER_H_
#define PROJECTZ_NPROXY_CACHESERVER_H_

#include <Dispatcher/Session.h>
#include <Dispatcher/Timer.h>
#include <Dispatcher/NSession/State.h>
#include <Network/Static.h>
#include "../../../protocol/Cache.h"

#include "Session.h"

namespace ProjectZ { namespace NProxy {

class CacheServer : public Session::IOwner, public::Dispatcher::Timer::IObserver
{
public:
	class Msg
	{
	public:
		static void OnOpenAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket );
		static void OnCloseAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket );
		static void OnUserInfoAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket );
		static void OnCharacterInfoAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket );
		static void OnFlushCharacterInfoAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket );
		static void OnFlushUserInfoAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket );
		static void OnRemoveUserAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket );
		static void OnFlushUserSlotInfoAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket );

		static void OnNewCharacterInfoAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket );
	};

public:
	class State : public ::Dispatcher::NSession::State
	{
	public:
		State()
		{
			AddCommand( CacheOpenAck::MSG_ID, Msg::OnOpenAck);
			AddCommand( CacheCloseAck::MSG_ID, Msg::OnCloseAck);

			AddCommand( UserInfoAck::MSG_ID, Msg::OnUserInfoAck);
			AddCommand( CharacterInfoAck::MSG_ID, Msg::OnCharacterInfoAck);
			AddCommand( FlushCharacterInfoAck::MSG_ID, Msg::OnFlushCharacterInfoAck);
			AddCommand( FlushUserInfoAck::MSG_ID, Msg::OnFlushUserInfoAck);
			AddCommand( RemoveUserAck::MSG_ID, Msg::OnRemoveUserAck);

			AddCommand( NewCharacterInfoAck::MSG_ID, Msg::OnNewCharacterInfoAck);
			AddCommand( FlushUserSlotInfoAck::MSG_ID, Msg::OnFlushUserSlotInfoAck);
		}

		~State() {}
	};

public:
	CacheServer();
	virtual ~CacheServer();

	bool 	Connect(int idx, std::string strIP, int port);
	void	OnDisconnect();
	virtual bool OnTime(int id, void* param);

	template<class T> void SendMessage(const T& msg)
	{
		if (false == _bConnect)
			return;

		::Network::Packet* pPacket = ::Network::GETPACKETPOOL()->SEND_NEW();
		char* pBuf = pPacket->GetOffsetPtr();
		if(false == msg.Store(&pBuf))
		{
			::Network::GETPACKETPOOL()->SEND_DEL(pPacket);
			return;
		}
		pPacket->SetLen(msg.Size());
		pPacket->MakePacketNoTail(T::MSG_ID);

		_pSession->SendPacket(pPacket, true);
	}

	int 		GetIdx() { return _idx; }

private:
	void	setTime();

private:
	//::Dispatcher::Session * _pSession;
	Session * _pSession;
	int 		_idx;
	bool		_bConnect;
	::Network::Session::Info _clsInfo;
};

} /*NProxy*/ } /*ProjectZ*/

#endif /* PROJECTZ_NPROXY_CACHESERVER_H_ */
